/**
 * @api post control.
 *
 * User: yunshengzhu
 * Date: 2020/12/1
 * Time: 下午2:41
 */
package control

import (
	"card-platform/config"
	"card-platform/model"
	"encoding/json"
	"errors"
	"fmt"
	"pkg/cfg"
	"pkg/utils"
	"time"
)

// swagger:operation POST /userInfo 用户类 userInfoReq
// ---
// summary: 获取用户信息详情 /userInfo.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/userResp"
func (a *User) UserInfo(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	user, err := model.GetUserId(userId)
	if err != nil {
		return nil, -1, err
	}
	return user, config.OK, nil
}

// swagger:operation POST /setUserPhone 用户类 setUserPhoneReq
// ---
// summary: 设置手机号 /setUserPhone.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/okResp"
func (a *User) SetUserPhone(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := SetUserPhoneReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}
	err = model.UpdateUserPhone(userId, req.Phone)
	if err != nil {
		return nil, -1, err
	}
	return nil, config.OK, nil
}

// swagger:operation POST /userOrderList 用户类 userOrderListReq
// ---
// summary: 获取用户订单列表 /userOrderList.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/userOrderListResp"
func (a *User) UserOrderList(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := UserOrderListReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}
	resp := UserOrderListResp{}
	resp.Count, err = model.GetOrderUserIdCount(userId, req.Status, req.QrStatus, req.Typ)
	resp.List, err = model.GetOrderUserIdList(userId, req.Status, req.QrStatus, req.Typ, req.Page, req.Size)
	for idx, v := range resp.List {
		resp.List[idx].ProList = a.getUserOrderDetail(v.OrderNumber)
		resp.List[idx].Merchant, _ = model.GetMerchantMid(v.Mid)
	}
	return resp, config.OK, nil
}

// swagger:operation POST /userOrderDetail 用户类 userOrderDetailReq
// ---
// summary: 获取用户订单商品详情 /userOrderDetail.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/userOrderDetailResp"
func (a *User) UserOrderDetail(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := UserOrderDetailReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}
	order, err := model.GetOrderNumber(req.OrderNumber)
	if err != nil {
		cfg.LogErr("err:", err)
	}
	if order.UserId != userId {
		cfg.LogErr("订单权限异常")
		return nil, config.ERR, errors.New("无效订单")
	}
	order.ProList = a.getUserOrderDetail(req.OrderNumber)
	order.Merchant, _ = model.GetMerchantMid(order.Mid)
	return order, config.OK, nil
}

func (a *User) getUserOrderDetail(orderNumber string) (list []model.OrderDetailDb) {
	list, err := model.GetOrderDetailList(orderNumber)
	if err != nil {
		cfg.LogErr("err:", err)
	}
	for idx, v := range list {
		temps := make([]string, 0)
		json.Unmarshal([]byte(v.Img), &temps)
		list[idx].Imgs = temps
	}
	return list
}

// swagger:operation POST /confirmReceipt 用户类 confirmReceiptReq
// ---
// summary: 订单确认收货 /confirmReceipt.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/userOrderListResp"
func (a *User) ConfirmReceipt(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := ConfirmReceiptReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}

	order, err := model.GetOrderUserIdAndOrderNumber(userId, req.OrderNumber)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}

	if order.Status != 2 {
		return nil, config.ERR, errors.New("当前状态不允许收货")
	}

	order.Status = 3
	order.ConfirmTime = time.Now().Unix()
	err = model.UpdateOrder(order)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}

	//分配利润
	go model.RemitAmount(order.OrderNumber)
	return nil, config.OK, err
}

// swagger:operation POST /subordinateList 用户类 subordinateListReq
// ---
// summary: 获取我的下级 /subordinateList.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/subordinateListResp"
func (a *User) SubordinateList(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := SubordinateListReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}
	resp := SubordinateListResp{}
	resp.List = make([]SubordinateList, 0)
	ls, err := model.GetUserPUserList(userId, req.Page, req.Size)
	if err != nil {
		cfg.LogErr("err:", err)
		return resp, config.ERR, err
	}
	for _, v := range ls {
		resp.List = append(resp.List, SubordinateList{
			Nickname:   v.Nickname,
			HeadImg:    v.HeadImg,
			CreateTime: v.CreateTime,
		})
	}
	resp.Count, _ = model.GetUserPUserIdCount(userId)
	return resp, config.OK, err
}

// swagger:operation POST /gainDetail 用户类 gainDetailReq
// ---
// summary: 收益明细 /gainDetail.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/gainDetailResp"
func (a *User) GainDetail(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := GainDetailReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}
	resp := GainDetailResp{}
	resp.ShareAmount, err = model.GetUserTransUserIdCount(userId, []int{3, 4})
	resp.SellAmount, err = model.GetUserTransUserIdCount(userId, []int{1})

	resp.SumAmount = resp.ShareAmount + resp.SellAmount
	resp.List, err = model.GetUserTransUserIdList(userId, req.Typ)
	return resp, config.OK, err
}

// swagger:operation POST /useOrder 用户类 useOrderReq
// ---
// summary: 点击使用生成二维码 /useOrder.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/useOrderResp"
func (a *User) UseOrder(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := UseOrderReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}

	order, err := model.GetOrderUserIdAndOrderNumber(userId, req.OrderNumber)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}

	if order.PayStatus != 1 {
		return nil, config.ERR, errors.New("当前用户状态不允许生成二维码")
	}

	if order.Typ != 2 {
		return nil, config.ERR, errors.New("订单类型异常")
	}

	if order.QrStatus == 1 {
		return nil, config.ERR, errors.New("卡券已核销")
	}

	order.QrCode = utils.MyMd5(fmt.Sprintf("%s_%d_%s", order.OrderNumber, userId, utils.GetRandomStr(20)))
	order.QrTime = time.Now().Unix()
	order.ExpQrTime = order.QrTime + 60*10
	err = model.UpdateOrderQr(order)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}

	merchant, _ := model.GetMerchantMid(order.Mid)
	resp := UseOrderResp{}
	resp.QrCode = order.QrCode
	resp.Merchant = merchant
	return resp, config.ERR, err
}

// swagger:operation POST /userWithdrawList 用户类 userWithdrawListReq
// ---
// summary: 获取用户提现列表 /userWithdrawList.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/userWithdrawListResp"
func (a *User) UserWithdrawList(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := UserWithdrawListReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}

	user, _ := model.GetUserId(userId)

	resp := UserWithdrawListResp{}
	resp.Count, err = model.GetUserWithdrawCount(userId)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}
	resp.List, err = model.GetUserWithdrawList(userId, req.Page, req.Size)
	resp.Amount, err = model.GetUserTransUserIdStatusAmount(userId, 1)
	resp.OnAmount, err = model.GetUserTransUserIdStatusAmount(userId, 2)
	resp.SumAmount = resp.Amount + resp.OnAmount
	resp.UserAmount = user.Amount

	return resp, config.ERR, err
}

// swagger:operation POST /applyUserWithdraw 用户类 applyUserWithdrawReq
// ---
// summary: 用户申请提现 /applyUserWithdraw.
// description: .
//// responses:
////   "200":
////     "$ref": "#/responses/okResp"
func (a *User) ApplyUserWithdraw(userId int64, data []byte, param Param) (out interface{}, code int, err error) {
	req := ApplyUserWithdrawReq{}
	err = json.Unmarshal(data, &req)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR_JSON, err
	}

	if req.Amount < 10000 {
		return nil, config.ERR, errors.New("提现金额不能小于100")
	}

	orderNumber := "T" + utils.GetRandomStr(20)
	userWithdraw := model.UserWithdrawDb{}
	userWithdraw.OrderNumber = orderNumber
	userWithdraw.UserId = userId
	userWithdraw.Amount = req.Amount
	userWithdraw.Username = req.Username
	userWithdraw.ProcedureAmount = req.Amount / 100 * 2
	user, err := model.GetUserId(userId)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}
	if user.Amount < uint64(req.Amount+userWithdraw.ProcedureAmount) {
		return nil, config.ERR, errors.New("余额不足")
	}

	userWithdraw.OpenId = user.OpenId
	userWithdraw.CreateTime = time.Now().Unix()
	userWithdraw.Status = 0
	err = model.CreateUserWithdraw(userWithdraw)
	if err != nil {
		cfg.LogErr("err:", err)
		return nil, config.ERR, err
	}

	go a.transfers(userWithdraw)
	return nil, config.OK, nil
}

func (a *User) transfers(obj model.UserWithdrawDb) error {
	wx := NewWeixinOrder()
	resp, err := wx.Transfers(obj.Username, obj.OpenId, obj.OrderNumber, uint64(obj.Amount), "用户提现")
	if err != nil {
		cfg.LogErr("err:", err)
	}

	if resp.ErrCodeDes == "余额不足" {
		cfg.LogErr("提现失败:", resp, obj)
		return errors.New("提现失败请稍后再试")
	}

	cfg.LogInfo("用户提现返回:", resp)
	go func(resp TransfersResult, obj model.UserWithdrawDb) {
		num := 0
		for {
			num++
			if num > 100 {
				return
			}
			time.Sleep(time.Second * 10)
			res, err := wx.Gettransferinfo(obj.OrderNumber)
			if err != nil {
				cfg.LogErr("err:", err)
				continue
			}

			if res.ReturnMsg=="指定单号数据不存在"{
				// 转账失败
				obj.Status = 2
				obj.CheckTime = time.Now().Unix()
				obj.Remark = fmt.Sprintf("付款账单:%s,商户单号:%s,发起转账时间:%s,企业付款成功时间:%s,收款用户姓名:%s,企业付款备注:%s,付款金额:%s,状态:%s,错误:%s",
					res.DetailId, res.PartnerTradeNo, res.TransferTime, res.PaymentTime, res.TransferName, res.Desc, res.PaymentAmount, res.Status,res.ReturnMsg)
				err = model.UpdateUserWithdraw(obj)
				return
			}

			if res.Status == "SUCCESS" {
				//转账成功
				obj.Status = 1
				obj.CheckTime = time.Now().Unix()
				obj.Remark = fmt.Sprintf("付款账单:%s,商户单号:%s,发起转账时间:%s,企业付款成功时间:%s,收款用户姓名:%s,企业付款备注:%s,付款金额:%s,状态:%s",
					res.DetailId, res.PartnerTradeNo, res.TransferTime, res.PaymentTime, res.TransferName, res.Desc, res.PaymentAmount, res.Status)
				err = model.UpdateUserWithdraw(obj)
			} else if res.Status == "FAILED" {
				// 转账失败
				obj.Status = 2
				obj.CheckTime = time.Now().Unix()
				obj.Remark = fmt.Sprintf("付款账单:%s,商户单号:%s,发起转账时间:%s,企业付款成功时间:%s,收款用户姓名:%s,企业付款备注:%s,付款金额:%s,状态:%s",
					res.DetailId, res.PartnerTradeNo, res.TransferTime, res.PaymentTime, res.TransferName, res.Desc, res.PaymentAmount, res.Status)
				err = model.UpdateUserWithdraw(obj)
			} else if res.Status == "PROCESSING" {
				continue
			}
		}
	}(resp, obj)

	return nil
}
